package com.payment.common.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.boot.env.PropertySourceLoader;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.io.support.SpringFactoriesLoader;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.BiPredicate;

public class ConfigFileApplicationListener implements EnvironmentPostProcessor, Ordered {

    private static final Logger LOGGER = LoggerFactory.getLogger(ConfigFileApplicationListener.class);

    private ResourcePatternResolver resourcePatternResolver;
    private List<PropertySourceLoader> propertySourceLoaders;

    public ConfigFileApplicationListener() {
        this.resourcePatternResolver = new PathMatchingResourcePatternResolver();
        this.propertySourceLoaders = SpringFactoriesLoader.
                loadFactories(PropertySourceLoader.class, getClass().getClassLoader());
    }

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        Resource[] resources;
        try {
            resources = resourcePatternResolver.getResources("classpath:/yml/**/*.*");
        } catch (IOException e) {
            LOGGER.error("读取资源配置文件错误：" + e.getMessage(), e);
            return;
        }
        if (resources.length < 1)
            return;
        MutablePropertySources destination = environment.getPropertySources();
        List<PropertySource<?>> loads = new ArrayList<>();

        BiPredicate<PropertySourceLoader,String> predicate = (loader, name)->
                Arrays.stream(loader.getFileExtensions())
                .anyMatch((fileExtension) -> StringUtils.endsWithIgnoreCase(name,
                        fileExtension));

        Arrays.stream(resources).forEach(resource ->
                propertySourceLoaders.forEach(loader -> {
                    if (predicate.test(loader, resource.getFilename())) {
                        try {
                            List<PropertySource<?>> load = loader.load("applicationConfig: [" + resource.getFilename() + "]", resource);
                            loads.addAll(load);
                        } catch (IOException e) {
                            LOGGER.error("读取资源配置文件错误：" + "applicationConfig: [" + resource.getFilename() + "]" + e.getMessage(), e);
                        }
                    }
                }));
        loads.forEach(destination::addLast);
    }

    @Override
    public int getOrder() {
        return org.springframework.boot.context.config.ConfigFileApplicationListener.DEFAULT_ORDER + 1;
    }
}
